package grape.mybatisplus;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by yangwei
 * Created at 2020/8/20 12:46
 */
public class ModuleGenerator {

    private static String starter = "starter";
    private static String Starter = "Starter";

    private static String pom_xml = "pom.xml";


    private static String starter_rest = "starter-rest";
    private static String starter_rest_client = "starter-rest-client";
    private static String starter_rest_client_impl = "starter-rest-client-impl";
    private static String starter_rest_server = "starter-rest-server";
    private static String starter_rest_spring_boot_starter = "starter-rest-spring-boot-starter";
    private static String starter_service = "starter-service";
    private static String starter_service_api = "starter-service-api";
    private static String starter_service_impl = "starter-service-impl";
    private static String starter_service_spring_boot_starter = "starter-service-spring-boot-starter";


    private static String moduleName = null;
    private static String port = null;

    public static void main(String[] args) {
        // 请小写
        moduleName = "house";
        port = "9110";

        generate();
    }

    public static String before() {

        // E:\gitee-source\grape
        String userDir = System.getProperty("user.dir");
        System.out.println("userDir = [" + userDir + "]");

        String starterPath = userDir + "\\modules\\" + starter;
        System.out.println("starterPath = [" + starterPath + "]");

        String tempPath = FileUtil.getTmpDirPath();
        System.out.println("tempPath = [" + tempPath + "]");

        String newTempStarterPath = tempPath + starter;
        System.out.println("newTempStarterPath = [" + newTempStarterPath + "]");
        FileUtil.del(newTempStarterPath);
        FileUtil.del(FileUtil.getParent(newTempStarterPath,1) + "\\" + moduleName);


        FileUtil.copy(starterPath, tempPath, true);
        System.out.println("复制到临时目录完成");



        return newTempStarterPath;
    }

    public static void generate() {
        String newTempStarterPath = before();

        handle(newTempStarterPath,starter_rest);
        handle(newTempStarterPath,starter_rest_client);
        handle(newTempStarterPath,starter_rest_client_impl);
        handle(newTempStarterPath,starter_rest_server);
        handle(newTempStarterPath,starter_rest_spring_boot_starter);
        handle(newTempStarterPath + "\\" + starter_service,   starter_service_api);
        handle(newTempStarterPath + "\\" + starter_service,   starter_service_impl);
        handle(newTempStarterPath,   starter_service);
        handle(newTempStarterPath,starter_service_spring_boot_starter);
        // 重命名starter本身

        deleteFileIml(newTempStarterPath);
        replacePom(newTempStarterPath);
        FileUtil.rename(new File(newTempStarterPath), moduleName, false, false);

        String userDir = System.getProperty("user.dir");
        FileUtil.copy(FileUtil.getParent(newTempStarterPath,1) + "\\" + moduleName, userDir + "\\modules", true);
    }
    /**
     * starter-rest
     * @param newTempStarterPath
     */
    public static void handle(String newTempStarterPath,String modulePath) {

        System.out.println("处理" + modulePath);

        String path = newTempStarterPath + "\\" + modulePath;
        System.out.println("starterRestPath = [" + path + "]");

        // 删除iml文件
        deleteFileIml(path);
        // pom处理
        replaceDocker(path);
        replacePom(path);
        // 包重命名
        reNamePackage(path);

        replaceSpringFactories(path);

        replaceConfig(path);
        // 模块重命名
        FileUtil.rename(new File(path), replaceModuleLower(modulePath,true), false, false);

        System.out.println("处理" + modulePath + "完成");
    }


    //*********************************** 以下是工具辅助*******************************************//
    public static String concatIml(String str) {
        return str + ".iml";
    }

    public static void deleteFileIml(String parentPath) {
        File[] ls = FileUtil.ls(parentPath);
        for (File file : ls) {
            if (file.getName().endsWith(".iml")) {
                FileUtil.del(file);
            }
        }
    }
    public static void reNamePackage(String projectPath){
        String javaPath = projectPath + "\\src\\main\\java";
        reNameJavaFile(javaPath);
        doReNamePackage(javaPath);
    }

    public static void reNameJavaFile(String javaPath) {
        if (!FileUtil.exist(javaPath)) {
            System.out.println("reNameJavaFile 路径不存在已忽略,javaPath = ["+ javaPath +"]");
            return;
        }
        File[] ls = FileUtil.ls(javaPath);
        if(ls == null || ls.length == 0){
            return;
        }
        for (File file : ls) {
            if (file.isDirectory()) {
                reNameJavaFile(FileUtil.getAbsolutePath(file));
            }else{
                if(file.getName().endsWith(".java")){
                    Map<String, String> params = new HashMap<>();
                    params.put(starter, StrUtil.toCamelCase(moduleName));
                    params.put(Starter, StrUtil.upperFirst(StrUtil.toCamelCase(moduleName)));
                    replaceFileContent(file.getAbsolutePath(),params);
                    // 文件
                    FileUtil.rename(file, replaceModuleUper(file.getName()), false, true);
                }

            }

        }
    }
    public static void doReNamePackage(String path){
        if (!FileUtil.exist(path)) {
            System.out.println("doReNamePackage 路径不存在已忽略,javaPath = ["+ path +"]");
            return;
        }
        File[] ls = FileUtil.ls(path);
        if(ls == null || ls.length == 0){
            return;
        }
        for (File file : ls) {
            if (file.isDirectory()) {
                if (file.getName().equals(starter)) {
                    doReNamePackage(FileUtil.getAbsolutePath(file));
                    FileUtil.rename(file, moduleName, false, false);

                }else{
                    doReNamePackage(FileUtil.getAbsolutePath(file));
                }
            }

        }
    }

    public static String replaceModule(String content,boolean withLine){
        return replaceModuleUper(replaceModuleLower(content,withLine));
    }
    public static String replaceModuleLower(String content,boolean withLine){
        String temp = starter;
        String tempModuleName = moduleName;
        if (withLine) {
            temp += "-";
            tempModuleName += "-";
        }
        return content.replace(temp, tempModuleName);
    }
    public static String replaceModuleUper(String content){
        return content.replace(Starter, StrUtil.upperFirst(StrUtil.toCamelCase(moduleName)));
    }

    public static void replaceDocker(String modulePath){
        if (!FileUtil.exist(modulePath + "\\docker")) {
            return;
        }
        Map<String, String> params = new HashMap<>();
        params.put("9999", port);
        params.put(starter, moduleName);

        replaceFileContent(modulePath + "\\docker\\docker-compose.yml", params);
        replaceFileContent(modulePath + "\\docker\\Dockerfile", params);
    }

    public static void replaceSpringFactories(String modulePath){
        Map<String, String> params = new HashMap<>();
        params.put(starter, moduleName);
        params.put(Starter, StrUtil.upperFirst(StrUtil.toCamelCase(moduleName)));

        replaceFileContent(modulePath + "\\src\\main\\resources\\META-INF\\spring.factories", params);
    }

    public static void replaceConfig(String modulePath){
        Map<String, String> params = new HashMap<>();
        params.put("9999", port);

        replaceFileContent(modulePath + "\\src\\main\\resources\\application.yml", params);
        Map<String, String> params1 = new HashMap<>();
        params1.put("grape-starter", "grape-" + moduleName);
        params1.put("starterDataSource.yaml", moduleName +  "DataSource.yaml");

        replaceFileContent(modulePath + "\\src\\main\\resources\\bootstrap.yml", params1);
    }
    public static void replacePom(String modulePath){
        Map<String, String> params = new HashMap<>();
        params.put("<artifactId>"+ starter +"</artifactId>","<artifactId>"+ moduleName +"</artifactId>");
        params.put("<artifactId>"+ starter_rest +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_rest,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_rest_client +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_rest_client,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_rest_client_impl +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_rest_client_impl,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_rest_server +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_rest_server,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_rest_spring_boot_starter +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_rest_spring_boot_starter,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_service +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_service,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_service_api +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_service_api,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_service_impl +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_service_impl,true) +"</artifactId>");
        params.put("<artifactId>"+ starter_service_spring_boot_starter +"</artifactId>","<artifactId>"+ replaceModuleLower(starter_service_spring_boot_starter,true) +"</artifactId>");
        params.put("<module>"+ starter_rest +"</module>","<module>"+ replaceModuleLower(starter_rest,true) +"</module>");
        params.put("<module>"+ starter_rest_client +"</module>","<module>"+ replaceModuleLower(starter_rest_client,true) +"</module>");
        params.put("<module>"+ starter_service_impl +"</module>","<module>"+ replaceModuleLower(starter_service_impl,true) +"</module>");
        params.put("<module>"+ starter_rest_client_impl +"</module>","<module>"+ replaceModuleLower(starter_rest_client_impl,true) +"</module>");
        params.put("<module>"+ starter_rest_server +"</module>","<module>"+ replaceModuleLower(starter_rest_server,true) +"</module>");
        params.put("<module>"+ starter_rest_spring_boot_starter +"</module>","<module>"+ replaceModuleLower(starter_rest_spring_boot_starter,true) +"</module>");
        params.put("<module>"+ starter_service +"</module>","<module>"+ replaceModuleLower(starter_service,true) +"</module>");
        params.put("<module>"+ starter_service_spring_boot_starter +"</module>","<module>"+ replaceModuleLower(starter_service_spring_boot_starter,true) +"</module>");
        params.put("<module>"+ starter_service_api +"</module>","<module>"+ replaceModuleLower(starter_service_api,true) +"</module>");
        params.put("<module>"+ starter_service_impl +"</module>","<module>"+ replaceModuleLower(starter_service_impl,true) +"</module>");
        replaceFileContent(modulePath + "\\" + pom_xml, params);
    }
    public static void replaceFileContent(String filePath, Map<String, String> params) {

        if (!FileUtil.exist(filePath)) {
            System.out.println("replaceFileContent 路径不存在已忽略,filePath = ["+ filePath +"]");
            return;
        }

        String content = FileUtil.readUtf8String(filePath);
        for (String key : params.keySet()) {
            System.out.println("replaceFileContent = [" + key + " = "+ params.get(key) +"],filePath = ["+ filePath +"]");
            content = content.replace(key, params.get(key));
        }
        FileUtil.writeUtf8String(content,filePath);
    }
    public static void replaceFileContent(String filePath,String key,String value) {
        Map<String, String> params = new HashMap<>();
        params.put(key, value);
        replaceFileContent(filePath, params);
    }
}
